package com.demo.config;

import com.demo.enums.LocalCacheEnum;
import com.github.benmanes.caffeine.cache.Caffeine;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author wangfengchen
 */
@Slf4j
@EnableCaching
@Configuration
public class LocalCacheConfig {


  /**
   * SimpleCacheManager和CaffeineCacheManager配置的区别：
   * SimpleCacheManager：
   * 这种缓存管理器允许你在应用程序启动时通过配置多个CaffeineCache来创建多个缓存。
   * 这种方式可以让你为每个方法单独配置缓存过期时间。
   * CaffeineCacheManager：
   * 这种缓存管理器使用了一个全局的Caffeine配置来创建所有的缓存。
   * 这种方式不能为每个方法单独配置缓存过期时间，但是可以在程序启动时配置全局的缓存配置，这样就可以轻松地设置所有方法的缓存过期时间。
   * 总结：
   * 如果你希望为每个方法单独配置缓存过期时间，那么建议使用第一种方式。
   * 否则，如果你希望设置全局的缓存配置，那么建议使用第二种方式。
   */
  @Bean
  public CacheManager cacheManager() {
    SimpleCacheManager cacheManager = new SimpleCacheManager();
    List<CaffeineCache> list = new ArrayList<>();
    // 循环添加枚举类中自定义的缓存
    for (LocalCacheEnum cacheEnum : LocalCacheEnum.values()) {
      list.add(new CaffeineCache(cacheEnum.getName(),
          Caffeine.newBuilder()
              // 初始的缓存空间大小
              .initialCapacity(cacheEnum.getInitSize())
              // 缓存的最大条数
              .maximumSize(cacheEnum.getMaxSize())
              // 最后一次写入后经过固定时间过期
              .expireAfterWrite(cacheEnum.getExpire(), TimeUnit.SECONDS)
              .build()));
    }
    cacheManager.setCaches(list);
    log.info("cacheManager加载完成");
    return cacheManager;
  }


}
